import 'dart:async';
import 'dart:convert';

import 'package:amap_location/amap_location.dart';
import 'package:auto_orientation/auto_orientation.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_app_upgrade/flutter_app_upgrade.dart';
import 'package:flutter_chip/utils/date_utils.dart';
import 'package:flutter_chip/utils/log_util.dart';
import 'package:flutter_chip/utils/sp_utils.dart';
import 'package:flutter_chip/utils/third_utils.dart';
import 'package:flutter_chip/utils/toast_utils.dart';
import 'package:flutter_chip/utils/websocket_utils.dart';
import 'package:flutter_chip/view/forum/view_forum.dart';
import 'package:flutter_chip/view/mine/view_mine.dart';
import 'package:flutter_chip/widget/widget_cupertino_delegate.dart';
import 'package:flutter_lifecycle_state/flutter_lifecycle_state.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:fsuper/fsuper.dart';
import 'package:jpush_flutter/jpush_flutter.dart';
import 'package:package_info/package_info.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provide/provide.dart';

import 'bean/ChatMsg.dart';
import 'bean/User.dart';
import 'config/Api.dart';
import 'config/Comm.dart';
import 'config/GlobalEvent.dart';
import 'config/Http.dart';
import 'config/Routers.dart';
import 'view/home/view_home.dart';
import 'view/news/view_news.dart';
import 'view/view_login.dart';
import 'widget/RouteSlide.dart';

Future<void> main() {
  final router = new Router();
  Routers.configureRoutes(router);
  AMapLocationClient.setApiKey(Comm.AMAP_IOSKEY);

  var providers = Providers();
  var user = User();
  providers..provide(Provider<User>.value(user));
  runApp(ProviderNode(
    child: MyApp(),
    providers: providers,
  ));
  SystemUiOverlayStyle systemUiOverlayStyle =
      SystemUiOverlayStyle(statusBarColor: Colors.transparent);
  SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
  ThirdUtils().initThird();
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    WebSocketUtils().initWebSocket();
    return BotToastInit(
      child: MaterialApp(
          localizationsDelegates: [
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
            const FallbackCupertinoLocalisationsDelegate()
          ],
          supportedLocales: [
            const Locale('zh', 'CH'),
            const Locale('en', 'US'),
          ],
          locale: const Locale('zh'),
          theme: ThemeData(primarySwatch: Colors.lightBlue),
          home: MyHomePage(),
          navigatorObservers: [BotToastNavigatorObserver(), routeObserver],
          onGenerateRoute: Routers.router.generator),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends StateWithLifecycle<MyHomePage> {
  int lastTime = 0;
  PageController pageController;
  int page = 0;
  JPush jPush = new JPush();
  User user;
  String city = '定位中';
  bool hasMsg = false;

  @override
  void onCreate() {
    super.onCreate();
    pageController = PageController(initialPage: this.page);
    jPush.addEventHandler(
        // 接收通知回调方法。
        onReceiveNotification: (Map<String, dynamic> message) async {
      print("flutter onReceiveNotification: $message");
    },
        // 点击通知回调方法。
        onOpenNotification: (Map<String, dynamic> message) async {
      print("flutter onOpenNotification: $message");
    },
        // 接收自定义消息回调方法。
        onReceiveMessage: (Map<String, dynamic> message) async {
      print("flutter onReceiveMessage: $message");
    });
    jPush.setup(appKey: "ad4ea61471e7ee9edee791fc", debug: true);
    jPush.getRegistrationID().then((pushId) {
      print("推送ID：$pushId");
    });
    _checkPersmission();
    _getPackageInfo();
    _onMsgEvent();
    _getMsgList();
    _updateVersion();
  }

  @override
  void onResume() {
    super.onResume();
    AutoOrientation.portraitAutoMode();
    _getUserInfo();
  }

  @override
  Widget build(BuildContext context) {
    Comm.screenWidth = MediaQuery.of(context).size.width;
    Comm.screenHeight = MediaQuery.of(context).size.height;
    user = Provide.value<User>(context);
    return WillPopScope(
        child: Scaffold(
            body: PageView(
              children: <Widget>[
                HomePage(city),
                ForumPage(),
                NewsPage(),
                MinePage()
              ],
              onPageChanged: onPageChanged,
              controller: pageController,
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: () {
                if (null == user.userId) {
                  Navigator.of(context).push(RouteSlide(LoginPage()));
                  return;
                }
                showModalBottomSheet(
                    context: context,
                    builder: (builder) {
                      return _bottomSheet();
                    });
              },
              child: Icon(
                Icons.add,
                color: Colors.white,
              ),
            ),
            floatingActionButtonLocation:
                FloatingActionButtonLocation.centerDocked,
            bottomNavigationBar: BottomAppBar(
              color: Colors.white,
              shape: CircularNotchedRectangle(),
              child: Padding(
                padding: EdgeInsets.fromLTRB(0, 6, 0, 6),
                child: Row(
                  mainAxisSize: MainAxisSize.max,
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: <Widget>[
                    FSuper(
                      width: 36,
                      height: 48,
                      onClick: () {
                        onTap(0);
                      },
                      child1: Icon(Icons.home, color: getColor(0)),
                      child1Margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
                      child2: Text("首页", style: TextStyle(color: getColor(0))),
                      child2Margin: EdgeInsets.fromLTRB(0, 12, 0, 0),
                    ),
                    FSuper(
                      width: 36,
                      height: 48,
                      onClick: () {
                        onTap(1);
                      },
                      child1: Icon(Icons.forum, color: getColor(1)),
                      child1Margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
                      child2: Text("论坛", style: TextStyle(color: getColor(1))),
                      child2Margin: EdgeInsets.fromLTRB(0, 12, 0, 0),
                    ),
                    FSuper(
                      width: 36,
                      height: 48,
                      child2: Text(
                        "发布",
                        style: TextStyle(color: Color(0XFF737373)),
                      ),
                      child2Margin: EdgeInsets.fromLTRB(0, 12, 0, 0),
                    ),
                    FSuper(
                      width: 36,
                      height: 48,
                      onClick: () {
                        onTap(2);
                      },
                      child1: Icon(Icons.mail, color: getColor(2)),
                      child1Margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
                      child2: Text("消息", style: TextStyle(color: getColor(2))),
                      child2Margin: EdgeInsets.fromLTRB(0, 12, 0, 0),
                      redPointSize: 8,
                      redPoint: hasMsg,
                      redPointOffset: Offset(2, 2),
                    ),
                    FSuper(
                      width: 36,
                      height: 48,
                      onClick: () {
                        onTap(3);
                      },
                      child1: Icon(Icons.person, color: getColor(3)),
                      child1Margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
                      child2: Text("我的", style: TextStyle(color: getColor(3))),
                      child2Margin: EdgeInsets.fromLTRB(0, 12, 0, 0),
                    )
                  ],
                ),
              ),
            )),
        onWillPop: () {
          int newTime = DateTime.now().millisecondsSinceEpoch;
          int result = newTime - lastTime;
          lastTime = newTime;
          if (result > 2000) {
            Toast.show('再按一次退出');
          } else {
            SystemNavigator.pop();
          }
          return null;
        });
  }

  @override
  void dispose() {
    super.dispose();
    AMapLocationClient.shutdown();
    GlobalEvent().eventBus.destroy();
  }

  ///定位权限获取
  void _checkPersmission() async {
    Map<Permission, PermissionStatus> statuses = await [
      Permission.location,
      Permission.storage,
      Permission.camera,
      Permission.phone,
    ].request();

    if (statuses[Permission.location].isDenied) {
      Toast.show("缺少定位权限");
      return;
    }

    AMapLocationClient.startup(new AMapLocationOption(
        desiredAccuracy: CLLocationAccuracy.kCLLocationAccuracyHundredMeters));

    //监听坐标实时变换
    AMapLocationClient.onLocationUpate.listen((AMapLocation loc) {
      if (!mounted) return;
      if (loc == null) {
        print('定位中...');
        return;
      }
      if (loc.isSuccess()) {
        if (loc.hasAddress()) {
          AMapLocationClient.stopLocation();
          Comm.province = loc.province;
          Comm.city = loc.city;
          Comm.district = loc.district;
          setState(() {
            city = loc.city;
          });
        } else {
          print(
              "定位成功: \n时间${loc.timestamp}\n经纬度:${loc.latitude} ${loc.longitude}\n ");
        }
      } else {
        print("定位失败: \n错误:{code=${loc.code},description=${loc.description}");
        AMapLocationClient.stopLocation();
      }
    });
    AMapLocationClient.startLocation();
  }

  ///页面滑动
  void onPageChanged(int value) {
    setState(() {
      this.page = value;
      if (this.page == 2) {
        hasMsg = false;
      }
    });
  }

  ///导航栏按钮颜色
  Color getColor(int value) {
    return this.page == value
        ? Theme.of(context).accentColor
        : Color(0XFF737373);
  }

  void onTap(int value) {
    pageController.jumpToPage(value);
  }

  ///发布弹出
  Widget _bottomSheet() {
    bool isVip = null != user && null != user.vip && user.vip == 1;
    return Stack(children: <Widget>[
      Container(
        height: 25,
        width: double.infinity,
        color: Colors.black54,
      ),
      Container(
          width: double.infinity,
          height: MediaQuery.of(context).size.width - 100,
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(20),
              topRight: Radius.circular(20),
            ),
          ),
          child: Column(
            children: <Widget>[
              SizedBox(height: 30),
              Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  mainAxisSize: MainAxisSize.max,
                  children: <Widget>[
                    Container(
                        padding: EdgeInsets.all(20),
                        child: Column(
                          mainAxisSize: MainAxisSize.max,
                          children: <Widget>[
                            GestureDetector(
                              child: Image.asset(
                                Comm.IMG_TOPIC,
                                width: 46,
                                height: 46,
                                color: Color(0xff16A05D),
                              ),
                              onTap: () {
                                Navigator.pop(context);
                                Routers.router.navigateTo(
                                    context, Routers.PAGE_ADDFORUM,
                                    transition: TransitionType.inFromRight);
                              },
                            ),
                            SizedBox(height: 6),
                            Text("发帖", style: TextStyle(fontSize: 16))
                          ],
                        )),
                    Container(
                        padding: EdgeInsets.all(20),
                        child: Column(
                          mainAxisSize: MainAxisSize.max,
                          children: <Widget>[
                            GestureDetector(
                              child: Image.asset(
                                Comm.IMG_TOPIC,
                                width: 46,
                                height: 46,
                                color: Color(0xffDD5044),
                              ),
                              onTap: () {
                                Navigator.pop(context);
                                Routers.router.navigateTo(
                                    context, Routers.PAGE_SHARE,
                                    transition: TransitionType.inFromRight);
                              },
                            ),
                            SizedBox(height: 6),
                            Text("分享文章", style: TextStyle(fontSize: 16))
                          ],
                        )),
                    Container(
                        padding: EdgeInsets.all(20),
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: <Widget>[
                            GestureDetector(
                              child: Image.asset(
                                Comm.IMG_PROFIT,
                                width: 46,
                                height: 46,
                                color: Color(0xffFFCE40),
                              ),
                              onTap: () {
                                Navigator.pop(context);
                                if (!isVip) {
                                  Toast.show("加入会员才可以赚钱哦~");
                                  return;
                                }
                                Routers.router.navigateTo(
                                    context, Routers.PAGE_ADDGOODS,
                                    transition: TransitionType.inFromRight);
                              },
                            ),
                            SizedBox(height: 6),
                            Text("赚钱", style: TextStyle(fontSize: 16))
                          ],
                        )),
                  ]),
              SizedBox(height: 30),
              ClipOval(
                child: Container(
                    width: 56,
                    height: 56,
                    color: Theme.of(context).accentColor,
                    child: IconButton(
                        icon: Icon(Icons.close, color: Colors.white),
                        color: Theme.of(context).accentColor,
                        onPressed: () {
                          Navigator.of(context).pop();
                        })),
              )
            ],
          ))
    ]);
  }

  ///获取用户信息
  void _getUserInfo() async {
    Http.get(Api.URL_INFO, successCallBack: (data) {
      SpUtils.put(SpUtils.SP_USER, data);
      //延时加载，防止异常 The method 'markNeedsBuild' was called on null.
      Future.delayed(Duration(milliseconds: 200)).then((e) {
        setState(() {
          user.update(User.fromJson(json.decode(data)));
          Comm.isLogin = true;
          Comm.userId = user.userId;
          WebSocketUtils().sendMessage("", "");
        });
      });
    });
  }

  ///获取版本信息
  void _getPackageInfo() async {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    Comm.versionName = "${packageInfo.version}";
    Comm.buildNumber = packageInfo.buildNumber;
    Comm.appName = packageInfo.appName;
    print("当前版本号：${Comm.versionName} ${Comm.buildNumber}");
  }

  ///版本更新检查
  void _updateVersion() {
    Http.get(Api.URL_PARAM_VERSION, successCallBack: (data) async {
      Map params = json.decode(data);
      if (params.containsKey("version")) {
        String version = params["version"];
        print("新版本：$version， 当前版本：${Comm.versionName}");
        if (version == Comm.versionName) {
          return;
        }
        var newVer = version.split(".");
        var oldVer = Comm.versionName.split(".");
        bool isUpdate = false;
        if (int.parse(newVer[0]) > int.parse(oldVer[0])) {
          isUpdate = true;
        } else if (int.parse(newVer[1]) > int.parse(oldVer[1])) {
          isUpdate = true;
        } else if (int.parse(newVer[2]) > int.parse(oldVer[2])) {
          isUpdate = true;
        }
        if (isUpdate) {
          String day = DateUtil.getDateStrByDateTime(DateTime.now(),
              format: DateFormat.YEAR_MONTH_DAY);
          String lastUpdate = await SpUtils.get("apkUpdate", "");
          if ("0" == params["mustUpdate"] && day == lastUpdate) {
            LogUtil.v("请求完成 day == lastUpdate");
            return;
          }
          SpUtils.put(
              "apkUpdate",
              DateUtil.getDateStrByDateTime(DateTime.now(),
                  format: DateFormat.YEAR_MONTH_DAY));

          String apkUrl = params["apkUrl"];
          if (!apkUrl.startsWith("http")) {
            apkUrl = Api.getUrl(apkUrl);
          }
          LogUtil.v("下载地址：$apkUrl");
          List<String> contents = List();
          contents.add("发布时间:${params["versionTime"]}");
          contents.add("更新信息：");
          contents.addAll(params["versionInfo"].toString().split("\\n"));
          AppUpgrade.appUpgrade(
            context,
            Future.value(
              AppUpgradeInfo(
                title: "新版本$version",
                contents: contents,
                force: "1" == params["mustUpdate"],
                apkDownloadUrl: apkUrl,
              ),
            ),
          );
        }
      }
    });
  }

  ///小红点监听
  void _onMsgEvent() {
    GlobalEvent().eventBus.on<ChatMsg>().listen((event) {
      print("收到eventBus数据：${event.toJson()}");
      if (!mounted) {
        return;
      }
      setState(() {
        hasMsg = this.page != 2;
      });
    });
  }

  ///获取消息列表更新小红点
  Future _getMsgList() async {
    Http.get("${Api.URL_PARAM_MSG}", successCallBack: (data) {
      int unRead = json.decode(data)["chat"] ?? 0;
      setState(() {
        hasMsg = unRead != 0;
      });
    });
  }
}
